﻿
using System.Collections;
using System.Collections.Generic;
using System.Data;
using System.Reflection;
using System.Text;
namespace System
{
    public static partial class Utility
    {
        #region [Data Conversions] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

        public static string ToCommaSeparatedValue(this DataTable pDt, string pColumnName)
        {
            if (pDt == null) return string.Empty;
            StringBuilder sb = new StringBuilder();

            foreach (DataRow item in pDt.Rows)
            {
                sb.Append(item[pColumnName].ToString() + ",");
            }
            return sb.ToString().TrimEnd(',');
        }
        public static string ToCommaSeparatedValue<T>(this List<T> pValue)
        {
            if (pValue == null) return string.Empty;
            StringBuilder sb = new StringBuilder();

            for (int i = 0; i < pValue.Count; i++)
            {
                sb.Append(pValue[i].ToString() + ",");
            }

            return sb.ToString().TrimEnd(',');
        }
        public static string ToCommaSeparatedValue<T>(this T[] pValue)
        {
            if (pValue.Length == 0) return string.Empty;
            StringBuilder sb = new StringBuilder();

            for (int i = 0; i < pValue.Length; i++)
            {
                sb.Append(pValue[i].ToString() + ",");
            }

            return sb.ToString().TrimEnd(',');
        }

        public static List<T> ToListArray<T>(this DataTable pDt, string pColumnName)
        {
            if (pDt == null) return null;
            List<T> value = new List<T>();
            foreach (DataRow item in pDt.Rows)
            {
                value.Add((T)Convert.ChangeType(item[pColumnName], typeof(T)));
            }
            return value;
        }
        /// <summary>
        /// Used to convert from Comma Separated value to ListArray
        /// </summary>
        public static List<T> ToListArray<T>(this string pValue)
        {
            if (string.IsNullOrEmpty(pValue)) return null;
            List<T> value = new List<T>();
            string[] parca = pValue.Split(',');

            for (int i = 0; i < parca.Length; i++)
            {
                value.Add((T)Convert.ChangeType(parca[i], typeof(T)));
            }

            return value;
        }

        /// <summary>
        /// Used to convert from ListArray to DataColumn
        /// </summary>
        public static DataTable ToDataColumn<T>(this List<T> pValue, string pColumnName)
        {
            DataTable oDt = new DataTable();
            if (pValue == null) return oDt;
            oDt.Columns.Add(pColumnName);

            for (int i = 0; i < pValue.Count; i++)
            {
                DataRow oRw = oDt.NewRow();
                oRw[0] = pValue[i].ToString();
                oDt.Rows.Add(oRw);
            }

            return oDt;
        }
        /// <summary>
        /// Used to convert from Comma Separated value to DataColumn
        /// </summary>
        public static DataTable ToDataColumn(this string pValue, string pColumnName)
        {
            if (string.IsNullOrEmpty(pValue)) return new DataTable();
            DataTable oDt = new DataTable();
            oDt.Columns.Add(pColumnName);
            string[] parca = pValue.Split(',');

            for (int i = 0; i < parca.Length; i++)
            {
                DataRow oRw = oDt.NewRow();
                oRw[0] = parca[i];
                oDt.Rows.Add(oRw);
            }

            return oDt;
        }
        /// <summary>
        /// Used to convert from ArrayList to DataColumn
        /// </summary>
        public static DataTable ToDataColumn(this ArrayList pValue, string pColumnName)
        {
            if (pValue == null) return new DataTable();

            DataTable oDt = new DataTable();
            oDt.Columns.Add(pColumnName);

            for (int i = 0; i < pValue.Count; i++)
            {
                DataRow oRw = oDt.NewRow();
                oRw[0] = pValue[i].ToString();
                oDt.Rows.Add(oRw);
            }

            return oDt;
        }

        /// <summary>
        /// Used to convert from DataColumn to ArrayList 
        /// </summary>
        public static ArrayList ToArrayList(this DataTable pDt, string pColumnName)
        {
            if (pDt == null) return null;
            ArrayList arrSayfaKeyler = new ArrayList();
            foreach (DataRow row in pDt.Rows)
            {
                arrSayfaKeyler.Add(row[pColumnName]);
            }
            return arrSayfaKeyler;
        }

        /// <summary>
        /// Used to convert from CommaSeparated to Array 
        /// </summary>
        public static T[] ToArray<T>(this string pValue)
        {
            if (string.IsNullOrEmpty(pValue)) return null;
            string[] parca = pValue.Split(',');
            T[] value = new T[parca.Length];

            for (int i = 0; i < parca.Length; i++)
            {
                value[i] = ((T)Convert.ChangeType(parca[i], typeof(T)));
            }

            return value;
        }

        /// <summary>
        /// Uset to convert from EntityList to DataTable
        /// </summary>
        public static DataTable ToDataTable<T>(this List<T> pList)
        {
            return ToDataTable<T>(pList, string.Empty);
        }
        /// <summary>
        /// Uset to convert from EntityList to DataTable
        /// </summary>
        public static DataTable ToDataTable<T>(this List<T> pList, string pDefaultColumnType)
        {
            DataTable dt = new DataTable();

            foreach (PropertyInfo info in typeof(T).GetProperties())
            {
                Type clmType = pDefaultColumnType == string.Empty ? info.PropertyType : Type.GetType(pDefaultColumnType);
                bool isNullable = false;
                
                if (clmType.IsGenericType && clmType.GetGenericTypeDefinition() == typeof(Nullable<>))
                {
                    Type[] typeArray = info.PropertyType.GetGenericArguments();
                    foreach (Type t in typeArray)
                    {
                        if (t != null)
                        {
                            clmType = t;
                            isNullable = true;
                            break;
                        }
                    }
                }
                
                DataColumn colum = new DataColumn(info.Name, clmType);
                if (isNullable) colum.AllowDBNull = true;
                dt.Columns.Add(colum);
            }
            foreach (T t in pList)
            {
                DataRow row = dt.NewRow();
                foreach (PropertyInfo info in typeof(T).GetProperties())
                {
                    row[info.Name] = info.GetValue(t, null);
                }
                dt.Rows.Add(row);
            }
            return dt;
        }

        /// <summary>
        /// Uset to convert from DataTable to EntityList 
        /// </summary>
        public static List<T> ToEntityList<T>(this DataTable pDt, T pList)
        {
            if (pDt == null) return null;
            List<T> lists = new List<T>(pDt.Rows.Count);

            foreach (DataRow row in pDt.Rows)
            {
                pList = Activator.CreateInstance<T>();

                for (int i = 0; i < pDt.Columns.Count; i++)
                {
                    string clmName = pDt.Columns[i].ColumnName;
                    if (row[clmName] == DBNull.Value) continue;

                    if (pList.GetType().GetProperty(clmName) == null) continue;

                    string type = pList.GetType().GetProperty(clmName).PropertyType.FullName;

                    if (type.Contains(DataTypes.Int))
                        pList.GetType().GetProperty(clmName).SetValue(pList, Convert.ToInt32(row[clmName]), null);

                    else if (type.Contains(DataTypes.String))
                        pList.GetType().GetProperty(clmName).SetValue(pList, Convert.ToString(row[clmName]), null);

                    else if (type.Contains(DataTypes.Long))
                        pList.GetType().GetProperty(clmName).SetValue(pList, Convert.ToInt64(row[clmName]), null);

                    else if (type.Contains(DataTypes.Short))
                        pList.GetType().GetProperty(clmName).SetValue(pList, Convert.ToInt16(row[clmName]), null);

                    else if (type.Contains(DataTypes.Decimal))
                        pList.GetType().GetProperty(clmName).SetValue(pList, Convert.ToDecimal(row[clmName]), null);

                    else if (type.Contains(DataTypes.Double))
                        pList.GetType().GetProperty(clmName).SetValue(pList, Convert.ToDouble(row[clmName]), null);

                    else if (type.Contains(DataTypes.Byte))
                        pList.GetType().GetProperty(clmName).SetValue(pList, Convert.ToByte(row[clmName]), null);

                    else if (type.Contains(DataTypes.Boolean))
                        pList.GetType().GetProperty(clmName).SetValue(pList, Convert.ToBoolean(row[clmName]), null);

                    else if (type.Contains(DataTypes.DateTime))
                        pList.GetType().GetProperty(clmName).SetValue(pList, Convert.ToDateTime(row[clmName]), null);

                    else continue;
                }
                lists.Add(pList);
            }

            return lists;
        }

        public static T Factory<T>() where T : new()
        {
            return new T();
        }

        #endregion

        #region [Html Conversions] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

        public static string EncodingMeta = @"<META HTTP-EQUIV='Content-Type' CONTENT='text/html; charset=windows-1254'/>
											  <META HTTP-EQUIV='Content-Type' CONTENT='text/html; charset=ISO-8859-9'/>";

        private static string TableTag = "<table id='tableHtmlData' width='100%' style='height:20px;'>{0}</table>";

        private static string mHtmlTableBgColor = string.Empty;
        public static string HtmlTableBgColor { get { return mHtmlTableBgColor; } set { mHtmlTableBgColor = value; } }
        private static string mHtmlTableAlterRowBgColor = "#f0f8ff";
        public static string HtmlTableAlterRowBgColor { get { return mHtmlTableAlterRowBgColor; } set { mHtmlTableAlterRowBgColor = value; } }

        public static void SetHtmlTableBgColorsToDefault()
        {
            HtmlTableBgColor = string.Empty;
            HtmlTableAlterRowBgColor = "#f0f8ff";
        }

        private static string GetHtmlTableBgColor(int i)
        {
            string bgColor = string.Empty;
            string bgColorStyle = "style='background-color:{0}'";
            if (i % 2 == 1)
                bgColor = string.Format(bgColorStyle, HtmlTableBgColor);
            else
                bgColor = !String.IsNullOrEmpty(HtmlTableAlterRowBgColor) ? string.Format(bgColorStyle, HtmlTableAlterRowBgColor) : string.Empty;

            return bgColor;
        }

        /// <summary>
        /// DataTable olarak gönderilen bir verinin istenen kolonunu Html tablo olarak geri döndürür
        /// </summary>
        public static string ToHtmlTable(this DataTable pOdt, string pColumnName)
        {
            string htmlResult = string.Empty;
            string bgColor = string.Empty;
            int i = 0;

            foreach (DataRow row in pOdt.Rows)
            {
                bgColor = GetHtmlTableBgColor(i++);
                htmlResult += string.Format("<tr><td {1}>{0}</td></tr>", row[pColumnName].ToString(), bgColor);
            }
            htmlResult = string.Format(TableTag, htmlResult);
            SetHtmlTableBgColorsToDefault();
            return htmlResult;
        }
        /// <summary>
        /// Virgüllerle ayrışmıi bir string değeri Html tablo olarak geri döndürür
        /// </summary>
        public static string ToHtmlTable(this string pValue)
        {
            string htmlResult = string.Empty;
            string bgColor = string.Empty;
            int i = 0;
            string[] parca = pValue.Split(',');

            foreach (string item in parca)
            {
                bgColor = GetHtmlTableBgColor(i++);
                htmlResult += string.Format("<tr><td {1}>{0}</td></tr>", item, bgColor);
            }
            htmlResult = string.Format(TableTag, htmlResult);
            SetHtmlTableBgColorsToDefault();
            return htmlResult;
        }

        public static string ToHtmlTable(this DataTable pOdt, string pColumnName, string pUrlColumnName, string pToolTip, string pCssClassName)
        {
            string htmlResult = string.Empty;
            string bgColor = string.Empty;
            int i = 0;
            string css = string.Empty;
            if (!String.IsNullOrEmpty(pCssClassName)) css = string.Format("class='{0}'", pCssClassName);

            foreach (DataRow row in pOdt.Rows)
            {
                bgColor = GetHtmlTableBgColor(i++);
                string adi = row[pColumnName].ToString();
                string link = row[pUrlColumnName].ToString();

                htmlResult += string.Format("<tr><td {0}><a {4} title='{3}' href='{1}'>{2}</a></td></tr>", bgColor, link, adi, pToolTip, css);
            }
            htmlResult = string.Format(TableTag, htmlResult);
            SetHtmlTableBgColorsToDefault();
            return htmlResult;
        }

        public static string ToHtmlTable(this DataTable pOdt, string pColumnName, string pQueryStringColumnName, string pUrl, string pToolTip, string pCssClassName)
        {
            string htmlResult = string.Empty;
            string bgColor = string.Empty;
            int i = 0;
            string css = string.Empty;
            if (!String.IsNullOrEmpty(pCssClassName)) css = string.Format("class='{0}'", pCssClassName);

            string fullDataClmnName = pToolTip.Contains("UseAsColumnName") ? pToolTip.Replace("UseAsColumnName", string.Empty) : string.Empty;

            foreach (DataRow row in pOdt.Rows)
            {
                bgColor = GetHtmlTableBgColor(i++);

                string encryptedData = row[pQueryStringColumnName].ToString().Encrypt();
                string queryString = string.Format("?{0}={1}", pQueryStringColumnName, encryptedData);
                string fullURL = pUrl + queryString;

                string data = row[pColumnName].ToString();
                string toolTip = !String.IsNullOrEmpty(fullDataClmnName) ? row[fullDataClmnName].ToString() : pToolTip;

                htmlResult += string.Format("<tr><td {0}><a {4} title='{3}' href='{1}'>{2}</a></td></tr>", bgColor, fullURL, data, toolTip, css);
            }
            htmlResult = string.Format(TableTag, htmlResult);
            SetHtmlTableBgColorsToDefault();
            return htmlResult;
        }
        
        #endregion

        #region [Unit Conversions] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

        public static int ConvertCmToInch(this double pLength)
        {
            if (pLength > 0)
                return Convert.ToInt32(pLength * 28.8);
            else
                return 0;
        }

        #endregion

        #region [Type Conversions] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

        public static bool ToBool(this object pValue)
        {
            if (pValue == null) return false;
            if (pValue.ToString().ToLower() == "true") return true;
            if (pValue.ToString().ToLower() == "false") return false;
            if (!pValue.IsInteger()) return false;
            return Convert.ToBoolean(Convert.ToInt32(pValue));
        }

        public static char ToChar(this object pValue)
        {
            return Convert.ToChar(pValue);
        }

        public static byte ToByte(this object pValue)
        {
            return Convert.ToByte(pValue);
        }
        public static short ToShort(this object pValue)
        {
            return Convert.ToInt16(pValue);
        }
        public static int ToInt(this object pValue)
        {
            return Convert.ToInt32(pValue);
        }
        public static long ToLong(this object pValue)
        {
            return Convert.ToInt64(pValue);
        }
        public static decimal ToDecimal(this object pValue)
        {
            if (pValue is string) pValue = pValue.ToString().Replace(".", ",");
            return Convert.ToDecimal(pValue);
        }
        public static double ToDouble(this object pValue)
        {
            if (pValue is string) pValue = pValue.ToString().Replace(".", ",");
            return Convert.ToDouble(pValue);
        }

        public static DateTime? ToDateTime(this object pValue)
        {
            if (pValue == null) return null;
            return Convert.ToDateTime(pValue);
        }

        public static DateTime ToDateTime(this string pValue)
        {
            if (string.IsNullOrEmpty(pValue)) pValue = "01.01.1900";
            return Convert.ToDateTime(pValue);
        }

        #endregion
    }
}
